<?php

	class EbSQLModel
	{
		var $datasource;
				
		public function __construct($datasource = null)
		{
			if (is_null($datasource))
			{
				$this->datasource = EbModel::$defaultDataSource;
			}
			else
			{
				$this->datasource = $datasource;
			}
			
			if (is_null($this->datasource))
			{
				throw new Exception("The Data Source cannot be null!");
			}
			elseif (!is_object($this->datasource))
			{
				throw new Exception($this->datasource.' is an invalid data source!');
			}
		}
		
		public function create($tablename,$columns)
		{
			$sql = 'SHOW TABLE STATUS LIKE \''.$tablename.'\'';
			
			if (count($this->execute($sql)) > 0)
			{
				return false;
			}
			else
			{		
				$sql = 'CREATE TABLE IF NOT EXISTS '.$tablename.' (';
				$indexStr = '';
				
				foreach ($columns AS $column)
				{
					$sql .= $column->name.' '.$column->type;
					$sql .= ($column->not_null ? ' NOT NULL' : ' ');
					
					if ($column->key == EB_PRIMARY_KEY)
					{
						$sql .= ' PRIMARY KEY';
					}
					else if ($column->key == EB_UNIQUE_KEY)
					{
						$sql .= ' UNIQUE';
					}
					else if ($column->key == EB_INDEX_KEY)
					{
						$indexStr .= ',INDEX('.$column->name.')';
					}
					
					if ($column->autoincrement)
					{
						$sql .= ' AUTO_INCREMENT';
					}
					
					if (!is_null($column->default))
					{
						$sql .= ' DEFAULT \''.$column->default.'\'';
					}
					
					$sql .= ',';
				}
				
				$sql = substr($sql,0,strlen($sql) - 1);
				
				if (strlen($indexStr) > 0)
				{
					$sql .= $indexStr;
				}
				
				$sql .= ') CHARACTER SET utf8';
			
				return $this->execute($sql);
			}
		}
				
		protected function escape($values, $quotes = true)
		{
			if (is_array($values)) 
			{
				foreach ($values as $key => $value) 
				{ 
					$values[$key] = $this->escape($value, $quotes); 
				} 
			} 
			else if ($values === null) 
			{ 
				$values = 'NULL'; 
			} 
			else if (is_bool($values)) 
			{ 
				$values = $values ? 1 : 0; 
			}
			/*else if (is_date($values))
			{
				return strtotime($values);
			}*/
			else if ($values === "NOW()")
			{
				return "NOW()";
			}
			else if (!is_numeric($values)) 
			{ 
				$values = mysql_real_escape_string($values); 
				
				if ($quotes) 
				{ 
					$values = '"' . $values . '"'; 
				} 
			}
			
			return $values; 
		} 		
		
		protected function execute($args)
		{				
			if (is_null($this->datasource))
			{
				throw new Exception('The data source must be non-null!');
			}
			else
			{
				if (is_null($args))
				{
					return;
				}
				
				$args = func_get_args();
				
				$query = array_shift($args);
				
				if (count($args) > 0)
				{
					$query = str_replace("'%s'", '%s', $query); // in case someone mistakenly already singlequoted it
					$query = str_replace('"%s"', '%s', $query); // doublequote unquoting
					$query = str_replace('%s', "'%s'", $query); // quote the strings
					//var_dump(vsprintf($query, $args));die();
					array_walk($args, array(&$this, 'escape_by_ref'));
	
					$query = vsprintf($query, $args);
				}		
				
				if (!is_object($this->datasource))
				{
					var_dump($this->datasource);die();
				}
				
				$results = $this->datasource->execute($query);
							
				if (is_null($results) || $results === false)
				{
					return array();
				}
				else
				{
					return $results;
				}	
			}
		}

		public function select($tablename,$fields = null,$whereClause = null,$orderby = null)
		{
			$sql = "SELECT * FROM ".$tablename;
			
			if (!is_null($whereClause) && strlen($whereClause) > 0)
			{
				$sql.= " WHERE $whereClause";
			}
			
			if (!is_null($orderby) && strlen($orderby) > 0)
			{
				$sql.= " ORDER BY $orderby";
			}			
						
			return $this->execute($sql);
		}
		
		public function delete($tablename,$w)
		{
			$sql = "DELETE FROM $tablename WHERE $w LIMIT 1";
			
			return $this->execute($sql);
		}
	
		public function insert($tablename,$vo)
		{
			if (is_array($vo))
			{
				$vo = EbToolkit::array2object($vo);
			}
		
			$sql = 'INSERT INTO '.$tablename.' (';
			$valueSql = '';
						
			foreach($vo as $key => $value) 
			{
				if ($key[0] != '_')
				{
					$sql .= "$key,";
					$valueSql .= $this->escape($value).',';
				}
			}
			
			$sql = substr($sql,0,strlen($sql) - 1);
			$valueSql = substr($valueSql,0,strlen($valueSql) - 1);
			
			$sql .= ') VALUES('.$valueSql.')';
			
			return $this->execute($sql);
		}
		
		public function update($tablename,$vo,$where)
		{
			$sql = 'UPDATE '.$tablename.' SET ';
			
			foreach($vo as $key => $value) 
			{
				if ($key[0] != '_')
				{
					$sql .= $key.'='.$this->escape($value).',';
				}
			}
			
			$sql = substr($sql,0,strlen($sql) - 1);
			
			$sql .= ' WHERE '.$where. ' LIMIT 1';
						
			return $this->execute($sql);
		}
		
		private function escape_by_ref(&$s) 
		{
			$s = $this->escape($s);
		}
	}